home *** CD-ROM | disk | FTP | other *** search
/ Aminet 23 / Aminet 23 (1998)(GTI - Schatztruhe)[!][Feb 1998].iso / Aminet / disk / misc / TransADF.lha / Source / defl_disk.c next >
C/C++ Source or Header  |  1997-12-05  |  7KB  |  224 lines

  1. #include <exec/types.h>
  2. #include <exec/memory.h>
  3. #include <devices/trackdisk.h>
  4. #include <dos/dos.h>
  5. #include <clib/exec_protos.h>
  6. #include <clib/dos_protos.h>
  7.  
  8. #include "zlib.h"
  9.  
  10. #include "defl_disk.h"
  11. #include "main.h"
  12. #include "td.h"
  13. #include "util.h"
  14. #include "errors.h"
  15.  
  16.  
  17. #define DD_TBTRACKS 1                           /* Tracks in dd_TrackBuf */
  18. #define DD_TBSIZE   (DD_TBTRACKS * TRACK_SIZE)  /* Bytes in dd_TrackBuf  */
  19. #define DD_FBSIZE   (32*1024)                   /* Bytes in dd_FileBuf   */
  20.  
  21. UBYTE *dd_TrackBuf;    /* Our input buffer - reads from disk. */
  22. UBYTE *dd_FileBuf;     /* Our output buffer - writes to file. */
  23.  
  24.  
  25. /*
  26. ** Deflate a disk into a file.
  27. ** Expects all fields of adfPkt to be set.
  28. */
  29. void deflDisk (struct ADF_Packet *adfPkt, ULONG deflLevel, STRPTR origName,
  30.                ULONG fileType)
  31. {
  32.   static z_stream defl_stream;
  33.   ULONG nextTrack, CRC, USize, CSize;
  34.   LONG DOSError;
  35.   BYTE TDError;
  36.   int zerr, ocnt, deflg, winbits;
  37.   
  38.   
  39.   /* Output info header */
  40.   FPrintf (StdErr, "Deflating from TrackDisk Unit %ld (DF%ld:) to %s.\n",
  41.                    adfPkt->diskUnit,
  42.                    adfPkt->diskUnit,
  43.                    adfPkt->ADFileName);
  44.   
  45.   FPrintf (StdErr, "Starting at track %ld, Ending at track %ld.\n",
  46.                    (adfPkt->startTrack>>1),
  47.                    (adfPkt->endTrack>>1));
  48.   
  49.   FPuts (StdOut, "Compressing disk as a ");
  50.   switch (fileType) {
  51.   case FT_ZLIB:      FPuts (StdOut, "ZLib");  break;
  52.   case FT_GZIP:      FPuts (StdOut, "GZip");  break;
  53.   case FT_PKZIP:     
  54.   case FT_PKZIP_ADD: FPuts (StdOut, "PKZip"); break;
  55.   }
  56.   FPuts (StdOut, " file.\n");
  57.   
  58.   
  59.   /* Allocate the buffers */
  60.   dd_TrackBuf = (UBYTE *)AllocVec (DD_TBSIZE, MEMF_CLEAR);
  61.   dd_FileBuf  = (UBYTE *)AllocVec (DD_FBSIZE, MEMF_CLEAR);
  62.   if (!dd_TrackBuf || !dd_FileBuf)
  63.   {
  64.     /* No Memory */
  65.     FPrintf (StdErr, "%s: Out of memory.\n", ProgName);
  66.     cleanExit(RETURN_FAIL, ERROR_NO_FREE_STORE);
  67.   }
  68.   
  69.   /* Output the file header */
  70.   if (writeHead (adfPkt->ADFile, origName, fileType) == FALSE)
  71.   {
  72.     DOSError = IoErr();
  73.     
  74.     FPrintf (StdErr, "%s: Error - Couldn't write file header.\n",ProgName);
  75.     
  76.     if (DOSError)
  77.       reportDOSError(DOSError);
  78.     
  79.     cleanExit (RETURN_FAIL, NULL);
  80.   }
  81.   
  82.   /* Initialise the z_stream */
  83.   if (fileType == FT_ZLIB) winbits = 15;
  84.   else winbits = -15; /* windowBits is passed < 0 to suppress zlib header */    
  85.   defl_stream.zalloc = Z_NULL;
  86.   defl_stream.zfree  = Z_NULL;
  87.   defl_stream.opaque = Z_NULL;
  88.   zerr = deflateInit2 (&defl_stream, deflLevel,
  89.                        Z_DEFLATED, winbits, 8, 0);
  90.   if (zerr != Z_OK)
  91.   {
  92.     FPrintf (StdErr, "%s: Deflate Init Error - ", ProgName);
  93.     reportZLibError (zerr);
  94.     if (defl_stream.msg) FPrintf (StdErr, "\t(%s)\n", defl_stream.msg);
  95.     cleanExit (RETURN_FAIL, NULL);
  96.   }
  97.     
  98.   /* Start deflateing */
  99.   defl_stream.avail_in  = 0;           /* Input buffer is empty    */
  100.   defl_stream.next_out  = dd_FileBuf;  /* Pointer to output buffer */
  101.   defl_stream.avail_out = DD_FBSIZE;   /* output buffer is empty   */
  102.   deflg = Z_NO_FLUSH;
  103.   CRC = crc32 (NULL, Z_NULL, 0);       /* Initialise the CRC       */
  104.   nextTrack = adfPkt->startTrack;
  105.   for (;;)
  106.   {
  107.     if (defl_stream.avail_in == 0)  /* Input is empty */
  108.       if (nextTrack <= adfPkt->endTrack)
  109.       {
  110.         /* Update progress report */
  111.         FPuts (StdOut, "\rReading   ");
  112.         FPUTS_TS (nextTrack, StdOut);
  113.         Flush (StdOut);
  114.         
  115.         /* Fill the input buffer from disk */
  116.         TDError = readTrack (dd_TrackBuf, DD_TBTRACKS, nextTrack, 
  117.                              adfPkt->diskReq);
  118.         if (TDError)
  119.         {
  120.           FPutC (StdOut, '\n');
  121.           FPrintf (StdErr, "%s: Error reading from DF%ld: - ",
  122.                            ProgName, adfPkt->diskUnit);
  123.           reportTDError (TDError);
  124.           deflateEnd (&defl_stream);
  125.           cleanExit (RETURN_FAIL, NULL);
  126.         }
  127.         
  128.         nextTrack++;
  129.         defl_stream.next_in  = dd_TrackBuf;
  130.         defl_stream.avail_in = DD_TBSIZE;
  131.       }
  132.     
  133.     if (defl_stream.avail_in == 0)  /* Still zero - no more input */
  134.       deflg = Z_FINISH;
  135.     else
  136.       /* New data - Update the CRC */
  137.       CRC = crc32 (CRC, dd_TrackBuf ,defl_stream.avail_in);
  138.     
  139.     /* Fill the output buffer with deflated data, and keep filling */
  140.     /* it until no more inflated data exists in the input buffer.  */
  141.     for (;;)
  142.     {
  143.       /* Check for Control-C break */
  144.       if (CTRL_C)
  145.       {
  146.         FPutC (StdOut, '\n');
  147.         FPrintf (StdErr, "%s - %s\n", breakText, ProgName);
  148.         deflateEnd (&defl_stream);
  149.         cleanExit (RETURN_WARN, NULL);
  150.       }
  151.       
  152.       /* Upate progress report */
  153.       FPuts (StdErr, "\rDeflating ");
  154.       Flush (StdErr);
  155.       
  156.       zerr = deflate (&defl_stream, deflg);
  157.       if (zerr < Z_OK)
  158.       {
  159.         FPutC (StdOut, '\n');
  160.         FPrintf (StdErr, "%s: Deflate error - ", ProgName);
  161.         reportZLibError (zerr);
  162.         if (defl_stream.msg) FPrintf (StdErr, "\t%s\n", defl_stream.msg);
  163.         deflateEnd (&defl_stream);
  164.         cleanExit (RETURN_FAIL, NULL);
  165.       }
  166.       
  167.       /* Flush the output buffer */
  168.       ocnt = DD_FBSIZE - defl_stream.avail_out;
  169.       if (ocnt) 
  170.       {
  171.         if ( Write (adfPkt->ADFile, dd_FileBuf, ocnt) != ocnt)
  172.         {
  173.           DOSError = IoErr();
  174.           
  175.           FPutC (StdOut, '\n');
  176.           FPrintf (StdErr, "%s: Error writing deflated data - ", ProgName);
  177.           reportDOSError(DOSError);
  178.           
  179.           cleanExit (RETURN_FAIL, DOSError);
  180.         }
  181.       }
  182.       defl_stream.next_out  = dd_FileBuf;
  183.       defl_stream.avail_out = DD_FBSIZE;
  184.       
  185.       if ((ocnt != DD_FBSIZE) || (zerr == Z_STREAM_END))
  186.         /* Last deflate() did not completely fill the output buffer,  */
  187.         /* thus no more data is pending, or we reached the end of the */
  188.         /* compressed data stream.                                    */
  189.         break;
  190.     }
  191.     if (zerr == Z_STREAM_END) break;
  192.   }
  193.   USize = defl_stream.total_in;
  194.   CSize = defl_stream.total_out;
  195.   
  196.   FPrintf (StdOut, "\rDeflated: %ld ==> %ld (%ld%%).   ",
  197.                    USize, CSize, ((CSize * 100) / USize));
  198.   Flush (StdOut);
  199.   
  200.   /* End the deflate process */
  201.   zerr = deflateEnd (&defl_stream);
  202.   if (zerr != Z_OK)
  203.   {
  204.     FPutC (StdOut, '\n');
  205.     FPrintf (StdErr, "%s: Deflate End Error - ", ProgName);
  206.     reportZLibError (zerr);
  207.     if (defl_stream.msg) FPrintf (StdErr, "\t(%s)\n", defl_stream.msg);
  208.     cleanExit (RETURN_FAIL, NULL);
  209.   }
  210.   
  211.   /* Finish the file */
  212.   if ( finishFile (adfPkt->ADFile, CRC, CSize, USize, fileType) == FALSE)
  213.   {
  214.     FPutC (StdOut, '\n');
  215.     FPrintf (StdErr, "%s: Error - Couldn't finish output file correctly.\n",
  216.                      ProgName);
  217.     cleanExit (RETURN_FAIL, NULL);
  218.   }
  219.   
  220.   /* Free and clear buffers */
  221.   FreeVec (dd_TrackBuf); dd_TrackBuf = NULL;
  222.   FreeVec (dd_FileBuf); dd_FileBuf = NULL;
  223. }
  224.